﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using clmbine.database.sqlite;
using System.Collections;

namespace clmbine.todo
{
    public class todo
    {
        #region properties
        public int Seq { get; set; }
        public string Subject { get; set; }
        public string Memo { get; set; }
        public int Priority { get; set; }
        public int Postpone { get; set; }
        public int Estimate { get; set; }
        public int Spent { get; set; }
        public string IsStar { get; set; }
        public string IsReview { get; set; }
        public int IsCycle { get; set; }
        public int Depth { get; set; }
        public int Thread { get; set; }
        public int ProjectSeq { get; set; }
        public DateTime DueDate { get; set; }
        public DateTime RegDate { get; set; }
        public DateTime EndDate { get; set; }
        public DateTime UpdateDate { get; set; }
        #endregion

        private SqliteDB sqlite;
        public todo()
        {
        }

        public bool Create()
        {
            try
            {
                bool ReturnValue = true;
                sqlite = new SqliteDB();
                sqlite.Open();
                string sql = "insert into todo(subject, memo, priority, postpone, estimate, spent, isstar, isreview, iscycle, depth, thread, projectseq, dudate, regdate, enddate) values ";
                sql += "('" + Subject + "','" + Memo + "'," + Priority.ToString() + "," + Estimate.ToString() + ",0,'" + IsStar + "','" + IsReview + "'," + Depth.ToString() + "," + Thread.ToString() + "," + ProjectSeq.ToString() + ",";
                sql += "'" + DueDate.ToString() + "','" + RegDate.ToString() + "','" + EndDate.ToString() + "');";
                ReturnValue = (sqlite.Exec(sql)) ? true : false;
                sqlite.Close();
                return ReturnValue;
            }
            catch
            {
                return false;
            }
        }
        public bool Edit()
        {
            try
            {
                bool ReturnValue = true;
                sqlite = new SqliteDB();
                sqlite.Open();
                string sql = "update todo set ";
                sql += " subject = '" + Subject + "'";
                sql += ", memo = '"+Memo+"'";
                sql += ", priority = " + Priority.ToString();
                sql += ", postpone = " + Postpone.ToString();
                sql += ", estimate = " + Estimate.ToString();
                sql += ", spent = " + Spent.ToString();
                sql += ", isstar = '"+IsStar+"'";
                sql += ", isreview = '"+IsReview+"'";
                sql += ", iscycle = '" + IsCycle + "'";
                sql += ", depth = " + Depth.ToString();
                sql += ", thread = " + Thread.ToString();
                sql += ", projectseq = " + ProjectSeq.ToString();
                sql += ", dudate = '" + DueDate.ToString() + "'";
                sql += ", enddate = '" + EndDate.ToString() + "'";
                sql += ", updatedate = '"+DateTime.Now.ToString()+"'";
                sql += " where seq = " + Seq.ToString();
                ReturnValue = (sqlite.Exec(sql)) ? true : false;
                sqlite.Close();
                return ReturnValue;
            }
            catch
            {
                return false;
            }
        }
        public bool Delete()
        {
            try
            {
                bool ReturnValue = true;
                sqlite = new SqliteDB();
                sqlite.Open();
                string sql = "delete todo where seq = " + Seq.ToString();
                ReturnValue = (sqlite.Exec(sql)) ? true : false;
                if (ReturnValue)
                {
                }
                sqlite.Close();
                return ReturnValue;
            }
            catch
            {
                return false;
            }
        }
        public bool DoPostpone()
        {
            try
            {
                Postpone++;
                bool ReturnValue = true;
                sqlite = new SqliteDB();
                sqlite.Open();
                string sql = "update todo set postpone = " + Postpone.ToString() + " where seq = " + Seq.ToString();
                ReturnValue = (sqlite.Exec(sql)) ? true : false;
                sqlite.Close();
                return ReturnValue;
            }
            catch
            {
                return false;
            }
        }
        public bool Done()
        {
            try
            {
                EndDate = DateTime.Now;
                bool ReturnValue = true;
                sqlite = new SqliteDB();
                sqlite.Open();
                string sql = "update todo set enddate = " + EndDate.ToString() + " where seq = " + Seq.ToString();
                ReturnValue = (sqlite.Exec(sql)) ? true : false;
                sqlite.Close();
                return ReturnValue;
            }
            catch
            {
                return false;
            }
        }
        //특정 Project로 이동
        public bool Move(project Proj)
        {
            if (UpdateThread())
            {
                ProjectSeq = Proj.Seq;
                Thread = this.GetNextPrjThread(Proj);
                this.Edit();
                return true;
            }
            else
                return false;
        }
        //특정 todo에 Sub Task로 삽입
        public bool SubTask(todo Todo)
        {
            bool ReturnValue = true;
            sqlite = new SqliteDB();
            sqlite.Open();
            string sql = "";
            if (Depth == 0)
            {
                //최상위 Depth인 경우,
                sql = "update todo set thread = thread + 1000 where projectseq = " + Todo.ProjectSeq.ToString() + " and thread > " + Todo.Thread.ToString() + " order by thread desc";
            }
            else
            {
                //하위 Depth인 경우,
                string strTopThreadNumber = ((((int)(Todo.Thread / 1000)) - 1) * 1000).ToString();
                sql = "update todo set thread = thread + 1 where projectseq = " + Todo.ProjectSeq.ToString() + " and thread <= " + Todo.Thread.ToString() + " and thread > " + strTopThreadNumber + " order by thread desc";
            }
            ReturnValue = (sqlite.Exec(sql)) ? true : false;
            sqlite.Close();
            return ReturnValue;
        }

        //순서 변경(특정 Todo 위로 이동)
        public bool Order(todo Todo)
        {
            bool ReturnValue = true;
            sqlite = new SqliteDB();
            sqlite.Open();
            string sql = "";
            if (Depth == 0)
            {
                //최상위 Depth인 경우,
                sql = "update todo set thread = thread + 1000 where projectseq = " + ProjectSeq.ToString() + " and thread > " + Todo.Thread.ToString() + " order by thread desc";
            }
            else
            {
                //하위 Depth인 경우,
                string strTopThreadNumber = ((((int)(Todo.Thread / 1000)) -1 ) * 1000).ToString();
                sql = "update todo set thread = thread + 1000 where projectseq = " + ProjectSeq.ToString() + " and thread <= " + Todo.Thread.ToString() + " and thread > " + strTopThreadNumber + " order by thread desc";
            }
            ReturnValue = (sqlite.Exec(sql)) ? true : false;
            sqlite.Close();
            return ReturnValue;
        }

        private int GetNextPrjThread(project Proj)
        {
            int returnValue = 1000;
            sqlite = new SqliteDB();
            sqlite.Open();
            string sql = "select max(thread) from todo where projectseq = " + Proj.Seq.ToString();
            string result = sqlite.QueryValue(sql);
            sqlite.Close();
            if (result != "")
            {
                returnValue = Convert.ToInt32(result) + 1000;
            }
            return returnValue;
        }
        //해당 Thread가 제거될때 사용
        private bool UpdateThread()
        {
            bool ReturnValue = true;
            sqlite = new SqliteDB();
            sqlite.Open();
            string sql = "";
            //현재 아이템의 위의 모든 것들을 아래로 한칸씩 이동
            if (Depth == 0)
            {
                sql = "update todo set thread = thread - 1000  where projectseq = " + ProjectSeq.ToString() + " and thread > " + Thread.ToString() + " order by thread desc";
            }
            else
            {
                sql = "update todo set thread = thread - 1  where projectseq = " + ProjectSeq.ToString() + " and thread > " + Thread.ToString() + " order by thread desc";
            }
            ReturnValue = (sqlite.Exec(sql)) ? true : false;
            sqlite.Close();
            return ReturnValue;
        }
    }
}
